#include "iic_my.h"

int IIC_SDA;
int IIC_CLK;
void IIC_SetPort(int sda,int clk){
	IIC_SDA = sda;
	IIC_CLK = clk;
}

int IIC_SdaRead(void){
	int READED;
	IoTGpioGetInputVal(IIC_SDA,&READED);
	printf("IIC_SdaRead %02x\n",READED);
	return READED;
}	

/*******************************************************************************
  * 函数名：IIC_Start
  * 功  能：起始信号
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void IIC_Start()
{
	printf("iic_start\n");
	IIC_SdaModeOut();
	IIC_SclModeOut();
	IIC_SdaOutput_H();
	IIC_SclOutput_H(); //初始都是高电平
	delay_us(5);//>4.7us
	IIC_SdaOutput_L(); //拉低SDA
	delay_us(4);//>4us
	IIC_SclOutput_L(); //拉低CLK
}
/*******************************************************************************
  * 函数名：IIC_Stop
  * 功  能：结束信号  clk高电平时存在高跳变
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void IIC_Stop(void)
{
	printf("IIC_Stop\n");
	IIC_SdaModeOut();
	IIC_SclOutput_L();
	delay_us(5);
	IIC_SdaOutput_L();
	delay_us(5);
	IIC_SclOutput_H();
	delay_us(5);//>4us
	IIC_SdaOutput_H();
	delay_us(4);//>4.7us

}
/*******************************************************************************
  * 函数名：IIC_Ack
  * 功  能：应答信号
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void IIC_Ack(void)
{
	printf("IIC_Ack\n");
	// 原代码
	// IIC_SdaModeOut();
	// IIC_SclOutput_L();
	// IIC_SdaOutput_L();
	// IIC_SclOutput_H();
	// delay_us(4);//>4us
	// IIC_SclOutput_L();

	// 新代码
	printf("IIC_Ack\n");
	IIC_SdaModeIn();
	IIC_SclOutput_L();
	IIC_SclOutput_H();
	delay_us(4);//>4us
	int ack= 1;
	if(ack = IIC_SdaRead()){ // change while to if to debug
		printf("ACK is %d \n",ack);
		delay_us(5);
	}
	printf("ACK is %d \n",ack);
	IIC_SclOutput_L();
	delay_us(5);
}
/*******************************************************************************
  * 函数名：IIC_NoAck
  * 功  能：非应答信号
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void IIC_NoAck(void)
{
	printf("IIC_NoAck\n");
	IIC_SdaModeOut();
	IIC_SclOutput_L();
	IIC_SdaOutput_H();
	IIC_SclOutput_H();
	delay_us(4);//>4us
	IIC_SclOutput_L();
}
/*******************************************************************************
  * 函数名：IIC_WaitAck
  * 功  能：等待应答信号
  * 参  数：无
  * 返回值：0应答成功，1应答失败
  * 说  明：从机把总线拉低，为应答成功
*******************************************************************************/
uint8_t IIC_WaitAck(void)
{
	printf("IIC_WaitAck\n");
	uint8_t u8ErrCnt = 0;
	IIC_SdaModeIn();//输入状态
	IIC_SdaOutput_H();
	IIC_SclOutput_H();
	while (IIC_SdaRead() == 1)
	{
		u8ErrCnt++;
		if (u8ErrCnt > 250)
		{
			IIC_Stop();//发送停止信号
		   	return 1;
		}
	}
	IIC_SclOutput_L();
	return 0;
}
/*******************************************************************************
  * 函数名：IIC_WriteByte
  * 功  能：SDA线上输出一个字节
  * 参  数：u8Data需要写入的数据
  * 返回值：无
  * 说  明：无
*******************************************************************************/
void IIC_WriteByte(uint8_t u8Data)
{
	printf("IIC_WriteByte %02x\n",u8Data);
	uint8_t i;
	uint8_t u8Temp;
	IIC_SdaModeOut();
	// 拉低SCL 后 设置好SDA 后 拉高SCL
	IIC_SclOutput_L();
	for (i = 0; i < 8; i++)
	{
		delay_us(2);
		#ifdef IIC_LSB//低位在前
		u8Temp = ((u8Data << (7 - i)) & 0x80);
		(u8Temp == 0x80) ? (IIC_SdaOutput_H()) : (IIC_SdaOutput_L());		
		#else//高位在前
		u8Temp = ((u8Data >> (7 - i)) & 0x01);
		(u8Temp == 0x01) ? (IIC_SdaOutput_H()) : (IIC_SdaOutput_L());
		#endif	
		delay_us(2);	
		IIC_SclOutput_H();//时钟保持高电平
		delay_us(2);
		IIC_SclOutput_L();//时钟拉低，才允许SDA变化
		delay_us(2);
	}
}
/*******************************************************************************
  * 函数名：IIC_ReadByte
  * 功  能：读一个字节
  * 参  数：无
  * 返回值：读出的数据
  * 说  明：无
*******************************************************************************/
uint8_t IIC_ReadByte(void)
{
	uint8_t i;
	uint8_t bit = 0;
	uint8_t data = 0;
	IIC_SdaModeIn();//输入状态
	for (i = 0; i < 8; i++)
	{
		IIC_SclOutput_L();
		delay_us(2);
		IIC_SclOutput_H();
		bit = IIC_SdaRead();//读出1位
		#ifdef IIC_LSB//低位在前
		data |= (bit << i);		
		#else//高位在前
		data = (data << 1) | bit;
		#endif
		delay_us(2);
	}
	printf("IIC_ReadByte %02x\n",data);
	return data;
}